package android.slc.appbase.utils;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultCaller;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.blankj.utilcode.util.Utils;

import java.io.Serializable;

public class AppIntentUtils {
    public static final String KEY_INTENT_DATA = "intentData";

    public static <T extends Serializable> Intent getIntentByData(Class<? extends Activity> cls, T data) {
        Intent intent = new Intent(Utils.getApp(), cls);
        intent.putExtra(KEY_INTENT_DATA, data);
        return intent;
    }

    public static Intent getIntentByBundle(Class<? extends Activity> cls, Bundle bundle) {
        Intent intent = new Intent(Utils.getApp(), cls);
        if (bundle == null) {
            bundle = new Bundle();
        }
        intent.putExtras(bundle);
        return intent;
    }

    public static <T extends Serializable> T getDataByIntent(Intent intent) {
        if (intent != null) {
            return (T) intent.getSerializableExtra(KEY_INTENT_DATA);
        }
        return null;
    }

    public static <T extends Serializable> T getDataByIntent(Integer resultCode, Intent intent) {
        if (Activity.RESULT_OK == resultCode && intent != null) {
            return getDataByIntent(intent);
        }
        return null;
    }

    public static Bundle getBundleByIntent(Integer resultCode, Intent intent) {
        if (Activity.RESULT_OK == resultCode && intent != null) {
            return intent.getExtras();
        }
        return null;
    }

    public static <T extends Serializable> T getDataByBundle(Bundle bundle) {
        if (bundle != null) {
            return (T) bundle.getSerializable(KEY_INTENT_DATA);
        }
        return null;
    }

    public static <T extends Serializable> Bundle getBundleByData(T data) {
        Bundle bundle = new Bundle();
        if (data != null) {
            bundle.putSerializable(KEY_INTENT_DATA, data);
        }

        return bundle;
    }

    public static <T extends Serializable> Bundle putData2Bundle(T data, Bundle bundle) {
        if (bundle == null) {
            return getBundleByData(data);
        }
        bundle.putSerializable(KEY_INTENT_DATA, data);
        return bundle;
    }

    public static Bundle removeDataByBundle(Bundle bundle) {
        return removeDataByBundle(bundle, false);
    }

    public static Bundle removeDataByBundle(Bundle bundle, boolean autoCreate) {
        if (bundle == null && autoCreate) {
            return new Bundle();
        }
        if (bundle != null) {
            bundle.remove(KEY_INTENT_DATA);
        }
        return bundle;
    }

    public static <I extends Serializable, O extends Serializable> ActivityResultLauncher<I> registerForActivityResult(
            ActivityResultCaller activityResultCaller,
            Class<? extends Activity> cls,
            ActivityResultCallback<O> oActivityResultCallback) {
        return activityResultCaller.registerForActivityResult(new ActivityResultContract<I, O>() {
            @NonNull
            @Override
            public Intent createIntent(@NonNull Context context, I input) {
                return getIntentByData(cls, input);
            }

            @Override
            public O parseResult(int resultCode, @Nullable Intent intent) {
                return getDataByIntent(resultCode, intent);
            }
        }, oActivityResultCallback);
    }

    public static <O extends Serializable> ActivityResultLauncher<Bundle> registerForActivityResultInBundle(
            ActivityResultCaller activityResultCaller,
            Class<? extends Activity> cls,
            ActivityResultCallback<O> oActivityResultCallback) {
        return activityResultCaller.registerForActivityResult(new ActivityResultContract<Bundle, O>() {
            @NonNull
            @Override
            public Intent createIntent(@NonNull Context context, Bundle input) {
                return getIntentByBundle(cls, input);
            }

            @Override
            public O parseResult(int resultCode, @Nullable Intent intent) {
                return getDataByIntent(resultCode, intent);
            }
        }, oActivityResultCallback);
    }

    public static <I extends Serializable> ActivityResultLauncher<I> registerForActivityResultOutBundle(
            ActivityResultCaller activityResultCaller,
            Class<? extends Activity> cls,
            ActivityResultCallback<Bundle> oActivityResultCallback) {
        return activityResultCaller.registerForActivityResult(new ActivityResultContract<I, Bundle>() {
            @NonNull
            @Override
            public Intent createIntent(@NonNull Context context, I input) {
                return getIntentByData(cls, input);
            }

            @Override
            public Bundle parseResult(int resultCode, @Nullable Intent intent) {
                return getBundleByIntent(resultCode, intent);
            }
        }, oActivityResultCallback);
    }

    public static ActivityResultLauncher<Bundle> registerForActivityResultInOutBundle(
            ActivityResultCaller activityResultCaller,
            Class<? extends Activity> cls,
            ActivityResultCallback<Bundle> oActivityResultCallback) {
        return activityResultCaller.registerForActivityResult(new ActivityResultContract<Bundle, Bundle>() {
            @NonNull
            @Override
            public Intent createIntent(@NonNull Context context, Bundle input) {
                return getIntentByBundle(cls, input);
            }

            @Override
            public Bundle parseResult(int resultCode, @Nullable Intent intent) {
                return getBundleByIntent(resultCode, intent);
            }
        }, oActivityResultCallback);
    }
}